package bma.common.langutil.ai;

import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import bma.common.langutil.ai.callback.AICallback;
import bma.common.langutil.ai.impl.AIServiceTC1;
import bma.common.langutil.ai.impl.AIStackTC1;
import bma.common.langutil.ai.stack.AIStack;
import bma.common.langutil.ai.stack.AIStackSimple;
import bma.common.langutil.ai.vm.AIContextVM;
import bma.common.langutil.ai.vm.AIVM;
import bma.common.langutil.core.ObjectUtil;

public class AIVMSampleTC {

	final org.slf4j.Logger log = org.slf4j.LoggerFactory
			.getLogger(AIVMSampleTC.class);

	AIVM main;

	@Before
	public void setupMain() throws Exception {
		main = new AIVM();
		main.initMain();
	}

	@After
	public void closeMain() {
		main.close();
	}

	/**
	 * load
	 */
	@Test
	public void loadTest() throws Exception {
		AIServiceTC1 s = new AIServiceTC1();
		s.setContext(new AIContextVM(main, null));

		for (int i = 0; i < 20; i++) {
			AIStack<String> stack = new AIStackTC1<String>();
			s.asynSay(stack, "HelloKitty " + i);
		}
		ObjectUtil.waitFor(this, 1000);
	}

	/**
	 * 基本的用例
	 */
	@Test
	public void baseUsecase() throws Exception {
		AIServiceTC1 s = new AIServiceTC1();
		AIStack<Boolean> stack = new AIStackTC1<Boolean>();
		boolean done = s.say(stack, "hello world");

		if (done) {
			log.info("call done");
		} else {
			log.info("asyn calling");
		}
		ObjectUtil.waitFor(this, 1000);
	}

	/**
	 * 异步的用例
	 */
	@Test
	public void asynUsecase() throws Exception {
		AIServiceTC1 s = new AIServiceTC1();
		s.setContext(new AIContextVM(main, null));
		AIStack<String> stack = new AIStackTC1<String>();
		boolean done = s.asynSay(stack, "HelloKitty");

		if (done) {
			log.info("call done");
		} else {
			log.info("asyn calling");
		}
		ObjectUtil.waitFor(this, 1000);
	}

	/**
	 * AIStackSimple的用例
	 * 
	 * @throws Exception
	 */
	@Test
	public void simpleUsecase() throws Exception {
		AIServiceTC1 s = new AIServiceTC1();
		s.setContext(main.createContext(null));

		AIStackSimple<String> stack = new AIStackSimple<String>(null);
		s.asynSay(stack, "HelloKitty");
		String word = stack.get(1, TimeUnit.SECONDS);
		log.info("call result = {}", word);
	}

	/**
	 * Callback的用例
	 * 
	 * @throws Exception
	 */
	@Test
	public void callbackUsecase() throws Exception {
		AIServiceTC1 s = new AIServiceTC1();
		s.setContext(main.createContext(null));

		AIStackSimple<String> stack = new AIStackSimple<String>(null);
		s.asynSay(stack, "HelloKitty");
		stack.callback(new AICallback<String>() {

			@Override
			public void onSuccess(String result) {
				log.info("call result = {}", result);
			}

			@Override
			public void onFailure(Throwable t) {
				log.info("call failure", t);
			}
		});
		ObjectUtil.waitFor(this, 1000);
	}

	/**
	 * 回调本AI进程的用例
	 * 
	 * @throws Exception
	 */
	@Test
	public void resultAtCurrentUsecase() throws Exception {
		AIServiceTC1 s = new AIServiceTC1();
		s.setContext(main.createContext(null));

		AIStack<String> stack = new AIStackTC1<String>();
		s.asynSay(AIUtil.reentrant(stack, main.createContext(null)),
				"HelloKitty");
		ObjectUtil.waitFor(this, 1000);
	}

	/**
	 * 标准的异步调用方式（结果回调本AI进程）
	 * 
	 * @throws Exception
	 */
	@Test
	public void standardAsynCall() throws Exception {
		// AIStack<Boolean> stack = new AIStackTC1<Boolean>();
		// AIUtil.asynExecute(main.createContext(null), stack,
		// new AISRun<Boolean>() {
		// @Override
		// public void execute() {
		// success(true);
		// }
		// });
		// ObjectUtil.waitFor(this, 1000);
	}

	/**
	 * 根据AI进程判断是否异步调用
	 * 
	 * @throws Exception
	 */
	@Test
	public void checkAndExecute() throws Exception {
		// AIStack<Boolean> stack = new AIStackTC1<Boolean>();
		// AIUtil.executeAt(main, stack, new AISRun<Boolean>() {
		// @Override
		// public void execute() {
		// log.info("main");
		// success(false);
		// }
		// });
		// AIUtil.executeAt(e1, stack, new AISRun<Boolean>() {
		// @Override
		// public void execute() {
		// log.info("e1");
		// success(true);
		// }
		// });
		// AIThread.currentThread().waitFor(1000);
	}
}
